#pragma once

//#include <vector>
#include "Array.h"
#include "Vector.h"

namespace maths
{
	/*start point & direction*/
	class __declspec(align(16)) CLine
	{
	protected:
		CVector4f m_Dir;
		CVector4f m_Point;

	public:
		CLine              ( );
		CLine              ( CVector4f &a_Dir, CVector4f &a_Point );
		CVector4f& Dir     ( );
		CVector4f& Point   ( );
	};

	/*(n, d) - two values to determine a plane*/
	class __declspec(align(16)) CPlane
	{
	protected:
		CVector4f m_NandD;

	public:
		CPlane         ( );
		CPlane         ( CVector4f &a_NandD );
		CPlane         ( CVector4f &a_Norm, mFloat a_D );
		mVoid    SetD ( mFloat a_D );
		mVoid    SetN ( CVector4f &a_Norm );
		mVoid    SetN ( mFloat x, mFloat y, mFloat z );
		CVector4f GetN ( );
		mFloat   GetD ( );
	};

	class CPointArray;
	/*axis-aligned box, defined by two extreme points*/
	class __declspec(align(16)) CAABox
	{
	protected:
		CVector4f m_Min;
		CVector4f m_Max;

	public:
		CAABox               ( );
		CAABox               ( CVector4f &a_Min, CVector4f &a_Max );
		CVector4f &Min       ( );
		CVector4f &Max       ( );
		mVoid GetPoints     ( CPointArray &a_Res );
		mBool Collide       ( CAABox &a_Collider );
		mBool LastLineISect ( CVector4f &a_Res, CLine &a_Line );
	};

    const mUInt g_uMaxPoints = 128;
	class CPointArray
	{
	protected:
		//std::vector < CVector4f > m_Points;
        CFixedArray< CVector4f, g_uMaxPoints > m_Points;

	public:
		~CPointArray();

		mVoid Transform ( CMatrix4x4f &a_Mtx );
		mVoid CalcAABBox( CAABox &a_Res );

		mVoid Push ( CVector4f &a_Point );
		mVoid Push ( CPointArray &a_Array );
		mVoid Clear( );
        mUInt Size ( );

		CVector4f & operator [] (mUInt32 a_Ind);
		/*std::vector < CVector4f > :: iterator Begin( );
		std::vector < CVector4f > :: iterator End  ( );*/
	};

	inline mInt32 alikeVector4(const CVector4f &a_V1, const CVector4f &a_V2, const mFloat epsilon);

	inline CVector4f ZShootRay(CVector4f &a_V1, CVector4f &a_V2, CVector4f &a_V3, CVector4f &a_Point);
}